/*
 * Copyright (c) 2008 Anshuman Manur <anshuman.manur@gmail.com>,
 * Lavanya Shastri <lavanya.shastri@gmail.com>
 * 
 * This file is part of Andronova.
 * 
 * Andronova is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 * 
 * Andronova is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *  
 * You should have received a copy of the GNU General Public License
 * along with Andronova.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * This file may use the functionality provided by the library
 * jid3lib version 0.5.4 (<http://sourceforge.net/projects/javamusictag/>).
 * jid3lib and its uses are covered by GNU Lesser General Public License.
 * 
 */

package com.googlecode.andronova.helper;

import java.io.File;
import java.io.IOException;

import org.farng.mp3.MP3File;
import org.farng.mp3.TagException;
import org.farng.mp3.id3.AbstractID3v2;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;

public class Library {
	
	public static final String GENRE[] = { 
		"Blues",
		"Classic Rock",
		"Country",
		"Dance",
		"Disco",
		"Funk",
		"Grunge",
		"Hip-Hop",
		"Jazz",
		"Metal",
		"New Age",
		"Oldies",
		"Other",
		"Pop",
		"R&B",
		"Rap",
		"Reggae",
		"Rock",
		"Techno",
		"Industrial",
		"Alternative",
		"Ska",
		"Death Metal",
		"Pranks",
		"Soundtrack",
		"Euro-Techno",
		"Ambient",
		"Trip-Hop",
		"Vocal",
		"Jazz+Funk",
		"Fusion",
		"Trance",
		"Classical",
		"Instrumental",
		"Acid",
		"House",
		"Game",
		"Sound Clip",
		"Gospel",
		"Noise",
		"AlternRock",
		"Bass",
		"Soul",
		"Punk",
		"Space",
		"Meditative",
		"Instrumental Pop",
		"Instrumental Rock",
		"Ethnic",
		"Gothic",
		"Darkwave",
		"Techno-Industrial",
		"Electronic",
		"Pop-Folk",
		"Eurodance",
		"Dream",
		"Southern Rock",
		"Comedy",
		"Cult",
		"Gangsta",
		"Top 40",
		"Christian Rap",
		"Pop/Funk",
		"Jungle",
		"Native American",
		"Cabaret",
		"New Wave",
		"Psychadelic",
		"Rave",
		"Showtunes",
		"Trailer",
		"Lo-Fi",
		"Tribal",
		"Acid Punk",
		"Acid Jazz",
		"Polka",
		"Retro",
		"Musical",
		"Rock & Roll",
		"Hard Rock",
		"Folk",
		"Folk-Rock",
		"National Folk",
		"Swing",
		"Fast Fusion",
		"Bebob",
		"Latin",
		"Revival",
		"Celtic",
		"Bluegrass",
		"Avantgarde",
		"Gothic Rock",
		"Progressive Rock",
		"Psychedelic Rock",
		"Symphonic Rock",
		"Slow Rock",
		"Big Band",
		"Chorus",
		"Easy Listening",
		"Acoustic",
		"Humour",
		"Speech",
		"Chanson",
		"Opera",
		"Chamber Music",
		"Sonata",
		"Symphony",
		"Booty Bass",
		"Primus",
		"Porn Groove",
		"Satire",
		"Slow Jam",
		"Club",
		"Tango",
		"Samba",
		"Folklore",
		"Ballad",
		"Power Ballad",
		"Rhythmic Soul",
		"Freestyle",
		"Duet",
		"Punk Rock",
		"Drum Solo",
		"A capella",
		"Euro-House",
		"Dance Hall" };
	
	private final SQLiteDatabase db;
	
	private long size;
	
	public Library(SQLiteDatabase db) {
		this.db = db;
		setSize();
	}
	
	public void setSize() {
		Cursor c = db.query(DBConstants.LIB_TABLE_NAME, null, null, null, null, null, null);
		if(c != null)
			size = c.count();
	}
	
	public long getSize() {
		return size;
	}
	
	public Cursor getCursor(String selection) {
		return db.query(DBConstants.LIB_TABLE_NAME, null, selection, null, null, null, null);
	}
	
	public Cursor getCursor(String selection, String column) {
		return db.query(DBConstants.LIB_TABLE_NAME, new String[] { DBConstants.CNAME_ID, column }, selection, null, column, null, column);
	}
	
	public void clear() {
		db.delete(DBConstants.LIB_TABLE_NAME, null, null);
	}
	
	public void insertMetaData(File f) {
		try {
				MP3File file = new MP3File(f);
				AbstractID3v2 tag = file.getID3v2Tag();
    		
				String path = f.getAbsolutePath();
				String title, artist, album, genre, year;
				
				if(tag != null) {
					title = tag.getSongTitle();
					artist = tag.getLeadArtist();
					album = tag.getAlbumTitle();
					genre = tag.getSongGenre();
					year = tag.getYearReleased();
				}
				else {
					title = f.getName();
					artist = "Unknown";
					album = "Unknown";
					genre = "Unknown";
					year = "";
				}
				
				if(title.equals(""))
					title = f.getName();
				if(artist.equals(""))
					artist = "Unknown";
				if(album.equals(""))
					album = "Unknown";
				if(genre.equals(""))
					genre = "Unknown";
				else if(!genre.equals("Unknown")) {
					if(genre.startsWith("("))
						genre = genre.substring(1, genre.length() - 1);
					if(Character.isDigit(genre.charAt(0))) {
						int i = Integer.parseInt(genre);
						genre = GENRE[i];
					}
				}
								
				
				ContentValues cv = new ContentValues();
				
				cv.put(DBConstants.CNAME_PATH, path);
				cv.put(DBConstants.CNAME_TITLE, title);
				cv.put(DBConstants.CNAME_ARTIST, artist);
				cv.put(DBConstants.CNAME_ALBUM, album);
				cv.put(DBConstants.CNAME_GENRE, genre);
				cv.put(DBConstants.CNAME_YEAR, year);
    		
				long status = db.insert(DBConstants.LIB_TABLE_NAME, null, cv);
				if(status == -1)
					throw new SQLiteException("Error Inserting into database.");
				size++;
		}
		catch(NullPointerException nullE) {
			//TODO: system log entry: illegal file
			return;
		}
		catch(TagException tagE) {
			//TODO: take action
			return;
		}
		catch(Exception e) {
			//TODO: throw exception. report error back to user dialog box
			System.out.println(e.toString());
			return;
		}		
	}
	
	public Song getSong(long id) throws IOException {
		Cursor c = db.query(DBConstants.LIB_TABLE_NAME, new String[] { DBConstants.CNAME_PATH }, DBConstants.CNAME_ID + "=\"" + id + "\"", null, null, null, null);
		c.first();
		String path = c.getString(c.getColumnIndex(DBConstants.CNAME_PATH));
		try {
			Song s = new Song(path);
			s.setLibId(id);
			return s;		
		}
		catch(TagException e) {
			return null;
		}
	}
	
	public void update(Song s) {
		AbstractID3v2 tag = s.getID3v2Tag();
		long id = s.getLibId();
		
		String title, artist, album, genre, year;
		
		title = tag.getSongTitle();
		artist = tag.getLeadArtist();
		album = tag.getAlbumTitle();
		genre = tag.getSongGenre();
		year = tag.getYearReleased();
		
		if(title==null || title.equals(""))
			title = s.getMp3file().getName();
		if(artist==null || artist.equals(""))
			artist = "Unknown";
		if(album==null || album.equals(""))
			album = "Unknown";
		if(genre==null || genre.equals(""))
			genre = "Unknown";
		else if(!genre.equals("Unknown")) {
			if(genre.startsWith("("))
				genre = genre.substring(1, genre.length() - 1);
			if(Character.isDigit(genre.charAt(0))) {
				int i = Integer.parseInt(genre);
				genre = GENRE[i];
			}
		}
		
		ContentValues cv = new ContentValues();
		
		cv.put(DBConstants.CNAME_TITLE, title);
		cv.put(DBConstants.CNAME_ARTIST, artist);
		cv.put(DBConstants.CNAME_ALBUM, album);
		cv.put(DBConstants.CNAME_GENRE, genre);
		cv.put(DBConstants.CNAME_YEAR, year);		
		
		db.update(DBConstants.LIB_TABLE_NAME, cv, DBConstants.CNAME_ID + "=\"" + id + "\"", null);
	}

	@Override
	protected void finalize() throws Throwable {
		try {
			db.close();
		}
		finally {
			super.finalize();
		}
	}
}
